package igz.fleaxy.fx {
	import com.greensock.TimelineMax;
	import flash.display.Bitmap;
	import com.greensock.TweenMax;
	import flash.display.BlendMode;
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.TimerEvent;
	import flash.filters.BlurFilter;
	import flash.filters.ColorMatrixFilter;
	import flash.filters.DisplacementMapFilter;
	import flash.filters.GlowFilter;
	import flash.geom.Point;
	import flash.utils.Timer;
	import igz.fleaxy.util.ImageUtil;
	import igz.fleaxy.util.ObjectUtil;
	/**
	 * ...
	 * @author Intelygenz | www.intelygenz.com
	 */
	public class FxHalo {

		static protected var _Targets:Array = [];
		static public function _GetTarget(p_displayObject:DisplayObject) : Object {
			var target : Object = null;
			for ( var f:uint = 0; f < _Targets.length; f++) {
				if (_Targets[f]["obj"] == p_displayObject) {
					target  = _Targets[f];
					break;
				}
			}
			return target;
		}

		static public function $Start(p_displayObject:DisplayObject, p_settings:Object = null) : void {
			var target : Object = _GetTarget(p_displayObject);
			if ( target != null ) {
				(target["fx"]as FxHalo)._StopHalo_OnComplete();
			}
			else {
				target = { "obj" : p_displayObject, "fx" : new FxHalo() };
				_Targets.push(target);
			}
			(target["fx"] as FxHalo)._StartHalo(target["obj"], p_settings);
		}

		static public function $Stop(p_displayObject:DisplayObject) : void {
			var target : Object = _GetTarget(p_displayObject);
			if ( target != null ) {
				(target["fx"]as FxHalo)._StopHalo(target["obj"]);
			}
		}

		protected var _Settings:Object = { "r" : 1
										 , "g" : 2
										 , "b" : 4
										 , "a" : 8
										 , "grayScale" : false
										 , "velX" : null
										 , "velY" : null
										 , "glowBlurX" : 15
										 , "glowBlurY" : 15
										 , "timeFadeIn" : 1
										 , "timeFadeOut" : 2
										 };

		protected var _Halo:Bitmap;
		protected var _HaloMask:Bitmap;
		protected var _HaloOffset:Array;
		protected var _Timer:Timer;
		protected var _Vel1:Number;
		protected var _Vel2:Number;
		protected var _Vel3:Number;
		protected var _Vel4:Number;
		protected var _Container:Sprite;
		protected var _DotGlowAnim:TimelineMax;

		public function FxHalo() {
			
		}

		protected function _StartHalo(p_displayObject:DisplayObject, p_settings:Object = null) : void {
throw new Error("Aún NO funciona correctamente!");
			ObjectUtil.$Merge(p_settings, _Settings);

			_Container = new Sprite();
			_Container.x = p_displayObject.x;
			_Container.y = p_displayObject.y;
			p_displayObject.parent.addChild(_Container);
			_Container.parent.swapChildren(p_displayObject, _Container);
			
			_Halo = ImageUtil.$GetBitmap(p_displayObject);
			_Container.addChild(_Halo);

			_HaloMask =  ImageUtil.$GetBitmap(_Halo);
			_Container.addChild(_HaloMask);

			_HaloOffset = [new Point(0,0),new Point(0,0),new Point(0,0),new Point(0,0)];

			_Container.alpha = 0;

			TweenMax.to(_Container, _Settings["timeFadeIn"], { yoyo : true, alpha : 1 } );

			_Vel1 = 5 - (Math.random() * 10);
			_Vel2 = 5 - (Math.random() * 10);
			_Vel3 = 5 - (Math.random() * 10);
			_Vel4 = 5 - (Math.random() * 10);

			_HaloMask.filters = [new BlurFilter(_Settings["glowBlurX"]/3, _Settings["glowBlurY"]/3) ];
			_HaloMask.blendMode = BlendMode.OVERLAY;
			_Halo.filters = [new BlurFilter(_Settings["glowBlurX"], _Settings["glowBlurY"], 2)];
			//_DotGlowAnim = new TimelineMax( { yoyo : true, repeat: -1 } );
			//_DotGlowAnim.insert( TweenMax.to(_Halo, 2, { alpha : 0.8, blurFilter : { blurX:_Settings["glowBlurX"]*2, blurY:_Settings["glowBlurY"]*2, quality:2 } } ), 0 );

			_Timer = new Timer(40);
			_Timer.addEventListener(TimerEvent.TIMER, _LoopHalo);
			_Timer.start();
			
			//var timer2:Timer = new Timer(5000);
			//timer2.addEventListener(TimerEvent.TIMER, _LoopBlend);
			//timer2.start();
		}

		protected function _LoopBlend(p_timerEvent:TimerEvent) : void {
			switch ( _HaloMask.blendMode ) {
				case BlendMode.NORMAL:
					_HaloMask.blendMode = BlendMode.ADD;
					break;
				case BlendMode.ADD:
					_HaloMask.blendMode = BlendMode.ALPHA;
					break;
				case BlendMode.ALPHA:
					_HaloMask.blendMode = BlendMode.DARKEN;
					break;
				case BlendMode.DARKEN:
					_HaloMask.blendMode = BlendMode.DIFFERENCE;
					break;
				case BlendMode.DIFFERENCE:
					_HaloMask.blendMode = BlendMode.ERASE;
					break;
				case BlendMode.ERASE:
					_HaloMask.blendMode = BlendMode.HARDLIGHT;
					break;
				case BlendMode.HARDLIGHT:
					_HaloMask.blendMode = BlendMode.INVERT;
					break;
				case BlendMode.INVERT:
					_HaloMask.blendMode = BlendMode.LAYER;
					break;
				case BlendMode.LAYER:
					_HaloMask.blendMode = BlendMode.LIGHTEN;
					break;
				case BlendMode.LIGHTEN:
					_HaloMask.blendMode = BlendMode.MULTIPLY;
					break;
				case BlendMode.MULTIPLY:
					_HaloMask.blendMode = BlendMode.OVERLAY;
					break;
				case BlendMode.OVERLAY:
					_HaloMask.blendMode = BlendMode.SCREEN;
					break;
				case BlendMode.SCREEN:
					_HaloMask.blendMode = BlendMode.SHADER;
					break;
				case BlendMode.SHADER:
					_HaloMask.blendMode = BlendMode.SUBTRACT;
					break;
				case BlendMode.SUBTRACT:
					_HaloMask.blendMode = BlendMode.NORMAL;
					break;
			}
			trace( _HaloMask.blendMode );
		}
		
		protected function _LoopHalo(p_timerEvent:TimerEvent) :void {
			_HaloOffset[0].x += _Vel1;
			_HaloOffset[1].y += _Vel2;
			_HaloOffset[3].x += _Vel3;
			_HaloOffset[2].y += _Vel4;
			_HaloMask.bitmapData.perlinNoise(_HaloMask.width, _HaloMask.height, 4, 1, false, false, _Settings["r"] | _Settings["g"] | _Settings["b"] | _Settings["a"]
											, _Settings["grayScale"]
											, _HaloOffset
											);
		}

		protected function _StopHalo(p_displayObject:DisplayObject) : void {
			if ( _Halo != null ) {
				_Timer.stop();
				TweenMax.killTweensOf(_Container);
				TweenMax.to(_Container, _Settings["timeFadeOut"], { alpha : 0, onComplete : _StopHalo_OnComplete } );
			}
		}

		protected function _StopHalo_OnComplete() : void {
			if ( _Timer != null ) {
				_Timer.stop();
				_Timer.removeEventListener(TimerEvent.TIMER, _LoopHalo);
				_Timer = null;
				//_DotGlowAnim.stop();
				TweenMax.killTweensOf(_Container);
				_Container.removeChild(_Halo);
				_Halo = null;
				_Container.removeChild(_HaloMask);
				_HaloMask = null;
				_HaloMask.bitmapData.dispose();
				_Container.parent.removeChild(_Container);
				_Container = null;
	
				ObjectUtil.$CleanMemory();
			}
		}

	}

}